import * as DocumentPicker from "expo-document-picker";
import * as FileSystem from "expo-file-system";
import * as ImagePicker from "expo-image-picker";
// 	•	expo-linking 主要用于处理 URL 操作，包括打开外部链接和处理深层链接。
import * as Linking from "expo-linking";
import * as MediaLibrary from "expo-media-library";
import * as Speech from "expo-speech";

// 	ScrollView: 用于包裹内容的容器，可以在内容超出容器边界时滚动。
// 	contentContainerStyle: 这里我们使用 flexGrow: 1 确保内容容器填充整个 ScrollView。这样可以使得 ScrollView 在内容较少时也能填满屏幕。
import {
  Alert,
  Button,
  FlatList,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from "react-native";
import React, { useRef, useState } from "react";

import { Audio } from "expo-av";
import { useNavigation } from "@react-navigation/native";

export default function TabOneScreen() {
  const navigation = useNavigation();
  const [loading, setLoading] = useState(false);

  const [text, setText] = useState("");
  const [recording, setRecording] = useState(null);
  const [recordedUri, setRecordedUri] = useState("");
  const [isRecording, setIsRecording] = useState(false);
  const [recordings, setRecordings] = useState([]);
  const [editingName, setEditingName] = useState({ uri: "", name: "" });
  const [isEditing, setIsEditing] = useState(false);
  const [saveDirectory, setSaveDirectory] = useState(
    FileSystem.documentDirectory
  );
  const singleTapRef = useRef(null);

  const speak = () => {
    Speech.speak(text);
  };

  const navigateRouteFn = () => {
    navigation.navigate("testnavigate");
  };
  /**
   * 请求存储录音位置的权限
   * @returns
   */
  const requestMediaLibraryPermissions = async () => {
    const { status } = await MediaLibrary.requestPermissionsAsync();
    if (status !== "granted") {
      alert("Permission to access media library is required!");
      return false;
    }
    return true;
  };

  const startRecording = async () => {
    try {
      const { status } = await Audio.requestPermissionsAsync();
      if (status !== "granted") {
        alert("Permission to access microphone is required!");
        return;
      }

      if (!saveDirectory) {
        alert("Please select a directory to save the recording.");
        return;
      }

      await Audio.setAudioModeAsync({
        allowsRecordingIOS: true,
        playsInSilentModeIOS: true,
      });

      const { recording } = await Audio.Recording.createAsync(
        Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
      );

      setRecording(recording);
      setIsRecording(true);
    } catch (err) {
      console.error("Failed to start recording", err);
    }
  };

  const stopRecording = async () => {
    setIsRecording(false);
    await recording.stopAndUnloadAsync();
    const uri = recording.getURI();
    setRecordedUri(uri);
    setRecording(null);

    // Store the new recording in the app
    if (saveDirectory) {
      const newUri = `${saveDirectory}/recording-${Date.now()}.m4a`;
      await FileSystem.copyAsync({ from: uri, to: newUri });
      alert(`Recording saved to: ${newUri}`);
      setRecordings([
        ...recordings,
        { uri: newUri, name: `Recording ${recordings.length + 1}` },
      ]);
    } else {
      alert("No directory selected, saving to default location.");
      setRecordings([
        ...recordings,
        { uri, name: `Recording ${recordings.length + 1}` },
      ]);
    }

    // TODO:结束录音之后，默认移动到公共目录，不然是暂时的
    // Move the recording to the public directory
    await moveRecordingToPublicDirectory(uri);
  };

  const moveRecordingToPublicDirectory = async (uri) => {
    try {
      // Request media library permissions
      const { status } = await MediaLibrary.requestPermissionsAsync();
      if (status !== "granted") {
        alert("Permission to access media library is required!");
        return;
      }

      // Define the new file path in the public directory
      // TODO：这里有一个问题，当前的调试模式，没有创建出来，当前这个包的公共目录
      const newUri = `${
        FileSystem.documentDirectory
      }recording-${Date.now()}.3gp`;

      // Move the file to the new location
      await FileSystem.moveAsync({
        from: uri,
        to: newUri,
      });

      // Save the file to the media library
      const asset = await MediaLibrary.createAssetAsync(newUri);
      await MediaLibrary.createAlbumAsync("Recordings", asset, false);
      alert(newUri);
      alert("Recording saved to public directory!");
    } catch (error) {
      console.error("Error moving recording to public directory", error);
      alert("Failed to save recording to public directory.");
    }
  };

  const playRecording = async (uri) => {
    // Ensure the URI starts with file:// if it's a local file
    const soundUri = uri.startsWith("file://") ? uri : `file://${uri}`;
    alert(soundUri);
    const { sound } = await Audio.Sound.createAsync({ uri: soundUri });
    await sound.playAsync();
  };

  const deleteRecording = (uri) => {
    setRecordings(recordings.filter((recording) => recording.uri !== uri));
  };

  const saveRecordingName = (uri) => {
    setRecordings(
      recordings.map((recording) =>
        recording.uri === uri
          ? { ...recording, name: editingName.name }
          : recording
      )
    );
    setEditingName({ uri: "", name: "" });
    setIsEditing(false);
  };

  const handlePress = (uri, name) => {
    if (singleTapRef.current) {
      clearTimeout(singleTapRef.current);
      singleTapRef.current = null;
      // Double tap detected
      setIsEditing(true);
      setEditingName({ uri, name });
    } else {
      singleTapRef.current = setTimeout(() => {
        singleTapRef.current = null;
        // Single tap detected
        playRecording(uri);
      }, 300);
    }
  };

  const pickSaveDirectory = async () => {
    try {
      const res = await DocumentPicker.getDocumentAsync({
        type: "*/*",
        // 若要允许 expo-file-system 在选取文件后立即读取文件，
        // 需要确保该 copyToCacheDirectory 选项设置为 true 。
        copyToCacheDirectory: true,
      });
      console.log(JSON.stringify(res));
      // 数据格式内容：{"assets":[{"mimeType":"application/epub+zip","uri":"content://com.android.providers.media.documents/document/document%3A728136","name":"半小时漫画中国哲学史（其实是一本严谨的极简中国哲学史！漫画科普开创者混子哥新作！全网粉丝1300万！）.epub","size":28176868}],"canceled":false}
      if (res?.assets[0]?.uri) {
        const directory = res?.assets[0]?.uri.substring(
          0,
          res?.assets[0]?.uri.lastIndexOf("/")
        );

        setSaveDirectory(directory);
        Alert.alert("Save directory selected", directory);
      } else {
        console.log("Document picking was cancelled");
        Alert.alert("Document picking was cancelled");
      }
    } catch (err) {
      console.error("Failed to pick directory", err);
    }
  };
  const saveFileBtn = async () => {
    const fileName = `${FileSystem.documentDirectory}example.txt`;
    const content = "This is a sample text file.";

    try {
      await FileSystem.writeAsStringAsync(fileName, content);
      alert("File saved successfully!");
    } catch (error) {
      alert("Error saving file: " + error.message);
    }
  };

  const saveRecording = async () => {
    alert("Saving recording..recordedUri.");
    alert(JSON.stringify(recordedUri));
    alert("Saving recording..saveDirectory.");
    alert(JSON.stringify(saveDirectory));

    if (!recordedUri || !saveDirectory) {
      Alert.alert("Please record a file and select a save directory first.");
      return;
    }

    const fileName = recordedUri.split("/").pop();
    const newUri = `${saveDirectory}/${fileName}`;

    Alert.alert(newUri);
    try {
      // await FileSystem.copyAsync({
      //   from: recordedUri,
      //   to: newUri,
      // });
      // Alert.alert("File saved successfully!", newUri);
      // 获取到刚刚写入本地的录音资源
      const videoUri = recordings[0]!.uri; // 替换为本地的音频文件 URI
      alert(`本地音频资源地址：${videoUri}`);
      const fileName = `${FileSystem.documentDirectory}3.3gp`;
      // 修改成视频资源写法测试一下
      // todo:expo-file-system 的 downloadAsync 方法主要用于从远程 URL 下载文件，
      // 而不是从本地文件系统复制文件。如果您要从本地 URI 复制文件，应该使用 FileSystem.copyAsync 方法，而不是 downloadAsync。

      const response = await FileSystem.copyAsync({
        from: videoUri,
        to: fileName,
      });
      alert("Video saved successfully at " + response);
    } catch (error) {
      console.error("Failed to save 录制的音频文件", error);
      Alert.alert("Failed to save 录制的音频文件", error.message);
    }
  };

  /**
   * 移动当前的录音音频文件到本地存储
   * @returns
   */
  const moveRecordingToStorage = async () => {
    // 文件初始位置
    const recordingUri = recordings[0]!.uri;
    // 文件目标位置
    const targetUri = `${FileSystem.documentDirectory}recordings/recording.3gp`;

    try {
      // 创建目标目录（如果不存在）
      await FileSystem.makeDirectoryAsync(
        `${FileSystem.documentDirectory}recordings`,
        { intermediates: true }
      );

      // 移动文件
      await FileSystem.moveAsync({
        from: recordingUri,
        to: targetUri,
      });
      alert(JSON.stringify(targetUri));
      // 确保目标目录存在
      const mediaLibraryPermission =
        await MediaLibrary.requestPermissionsAsync();
      if (mediaLibraryPermission.granted) {
        const asset = await MediaLibrary.createAssetAsync(targetUri);
        const album = await MediaLibrary.getAlbumAsync("Download");
        if (album == null) {
          await MediaLibrary.createAlbumAsync("Download", asset, false);
        } else {
          await MediaLibrary.addAssetsToAlbumAsync([asset], album, false);
        }
        alert("Recording moved to storage successfully!");
      } else {
        alert("Permission to access media library is required!");
      }
    } catch (error) {
      alert("Error moving recording: " + error.message);
    }
  };

  /**
   * 从手机库中选择图像和视频或使用相机拍照
   * @returns
   */
  const pickAndSaveVideo = async () => {
    // 请求权限
    const permissionResult =
      await ImagePicker.requestMediaLibraryPermissionsAsync();
    alert(JSON.stringify(permissionResult));
    if (permissionResult.granted === false) {
      alert("Permission to access camera roll is required!");
      return;
    }

    // 选择视频
    const pickerResult = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Videos,
      allowsEditing: true,
      quality: 1,
    });

    if (pickerResult.cancelled) {
      alert("pickerResult.cancelled");

      return;
    }
    // todo:注意案例这里的内容都是assets的内容
    const videoUri = pickerResult.assets[0]?.uri;
    alert(JSON.stringify(videoUri));
    // 检查 videoUri 是否有效
    if (!videoUri || typeof videoUri !== "string") {
      alert("Error: No video selected or invalid URI");
      return;
    }

    // 检查 URI 格式
    const isValidUri =
      /^content:\/\//.test(videoUri) || /^file:\/\//.test(videoUri);
    if (!isValidUri) {
      alert("Error: Invalid URI format");
      return;
    }

    const fileName = `${FileSystem.documentDirectory}selected_video.mp4`;

    try {
      // 检查 URI 是否可访问
      const fileInfo = await FileSystem.getInfoAsync(videoUri);
      if (!fileInfo.exists) {
        alert("Error: File does not exist");
        return;
      }

      // 复制文件
      await FileSystem.copyAsync({
        from: videoUri,
        to: fileName,
      });
      alert("Video saved successfully!");
    } catch (error) {
      alert("Error saving video: " + error.message);
    }
  };

  const handleError = (message) => {
    Alert.alert(message);
  };
  /**
   * 媒体图片功能选择
   * @returns
   */
  const pickAndSaveImage = async () => {
    // 请求权限
    const permissionResult =
      await ImagePicker.requestMediaLibraryPermissionsAsync();
    alert(JSON.stringify(permissionResult));
    if (permissionResult.granted === false) {
      alert("Permission to access camera roll is required!");
      return;
    }

    // 选择视频
    const pickerResult = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      quality: 1,
    });

    if (pickerResult.cancelled) {
      alert("pickerResult.cancelled");

      return;
    }
    // todo:注意案例这里的内容都是assets的内容
    const imageUri = pickerResult.assets[0]?.uri;
    alert(JSON.stringify(imageUri));
    // 检查 imageUri 是否有效
    if (!imageUri || typeof imageUri !== "string") {
      alert("Error: No video selected or invalid URI");
      return;
    }

    // 检查 URI 格式
    const isValidUri =
      /^content:\/\//.test(imageUri) || /^file:\/\//.test(imageUri);
    if (!isValidUri) {
      alert("Error: Invalid URI format");
      return;
    }
    // TODO:所有的图片
    const fileName = `${FileSystem.documentDirectory}selected_image.jpg`;

    try {
      // 检查 URI 是否可访问
      const fileInfo = await FileSystem.getInfoAsync(imageUri);
      if (!fileInfo.exists) {
        alert("Error: File does not exist");
        return;
      }

      // 复制文件
      await FileSystem.copyAsync({
        from: imageUri,
        to: fileName,
      });
      alert("image saved successfully!");
    } catch (error) {
      alert("Error saving image: " + error.message);
    }
  };
  /**
   * 打开外部url连接在应用内，不是webview，比如打开一个连接，到外部浏览器或应用
   */
  const handleOpenLink = () => {
    Linking.openURL("https://example.com");
  };

  const handleOpenBMapLink = () => {
    Linking.openURL("https://map.baidu.com/@12955443,4838689,13z");
  };
  /**
   * 打开系统日历
   */
  const handleSysDay = () => {
    // Linking.openURL("calshow://");
    Linking.openURL("content://com.android.calendar/time");
  };

  const handleOpenBaiduYun = () => {
    const baiduNetdiskUrl = "baiduyun://"; // 示例URL
    Linking.canOpenURL(baiduNetdiskUrl)
      .then((supported) => {
        if (supported) {
          return Linking.openURL(baiduNetdiskUrl);
        } else {
          alert("Baidu Netdisk is not installed on your device");
        }
      })
      .catch((err) => console.error("An error occurred", err));
  };

  const handleOpenAlipay = () => {
    const alipayUrl = "alipays://platformapi/startapp?appId=20000067"; // 示例URL
    Linking.canOpenURL(alipayUrl)
      .then((supported) => {
        if (supported) {
          return Linking.openURL(alipayUrl);
        } else {
          alert("Alipay is not installed on your device");
        }
      })
      .catch((err) => console.error("An error occurred", err));
  };

  const handleOpenDingTalk = () => {
    const dingtalkUrl = "dingtalk://dingtalkclient/page/link?url=your_url"; // 示例URL
    Linking.canOpenURL(dingtalkUrl)
      .then((supported) => {
        if (supported) {
          return Linking.openURL(dingtalkUrl);
        } else {
          alert("DingTalk is not installed on your device");
        }
      })
      .catch((err) => console.error("An error occurred", err));
  };

  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      <Text>语音朗读系统</Text>
      <TextInput
        style={{
          height: 40,
          borderColor: "gray",
          borderWidth: 1,
          width: "80%",
          marginBottom: 20,
        }}
        placeholder="Enter text to speak"
        onChangeText={setText}
        value={text}
      />
      <Button title="Speak" onPress={speak} />
      <Button title="第一步选择录音位置Directory" onPress={pickSaveDirectory} />

      <Button
        title={isRecording ? "Stop Recording" : "Start Recording"}
        onPress={isRecording ? stopRecording : startRecording}
      />
      {recordedUri ? (
        <Button
          title="Play Last Recording"
          onPress={() => playRecording(recordedUri)}
        />
      ) : null}
      <Button title="移动音频到本手机的位置" onPress={moveRecordingToStorage} />
      <Button title="保存录音Save Recording" onPress={saveRecording} />
      {/* <Button title="SaveFileTest保存文本" onPress={saveFileBtn} /> */}
      <Button title="useNavigate导航-testnavigate" onPress={navigateRouteFn} />

      <Button
        title="从手机库中选择视频或使用相机拍照,未来播放本地图片"
        onPress={pickAndSaveVideo}
      />

      <Button title="从手机库中选择本地图片" onPress={pickAndSaveImage} />

      <FlatList
        data={recordings}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({ item }) => (
          <View style={styles.recordingItem}>
            <TouchableOpacity onPress={() => handlePress(item.uri, item.name)}>
              {isEditing && editingName.uri === item.uri ? (
                <TextInput
                  style={styles.recordingNameInput}
                  onChangeText={(newName) =>
                    setEditingName({ ...editingName, name: newName })
                  }
                  value={editingName.name}
                />
              ) : (
                <Text style={styles.recordingNameText}>{item.name}</Text>
              )}
            </TouchableOpacity>
            {isEditing && editingName.uri === item.uri ? (
              <Button
                title="Save"
                onPress={() => saveRecordingName(item.uri)}
              />
            ) : (
              <Button title="Play" onPress={() => playRecording(item.uri)} />
            )}
            <Button title="Delete" onPress={() => deleteRecording(item.uri)} />
          </View>
        )}
        style={{ marginTop: 20, width: "80%" }}
      />
      <ScrollView contentContainerStyle={styles.containerScroll}>
        <TouchableOpacity
          style={styles.linkButton}
          onPress={handleOpenBMapLink}
        >
          <Text style={styles.linkButtonText}>Open打开百度地图网站</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.linkButton} onPress={handleOpenLink}>
          <Text style={styles.linkButtonText}>Open External Link到浏览器</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.linkButton}
          onPress={handleOpenBaiduYun}
        >
          <Text style={styles.linkButtonText}>Open Baidu Yun</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.linkButton}
          onPress={handleOpenDingTalk}
        >
          <Text style={styles.linkButtonText}>Open DingTalk</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.linkButton} onPress={handleOpenAlipay}>
          <Text style={styles.linkButtonText}>Open Alipay</Text>
        </TouchableOpacity>

        <TouchableOpacity style={styles.linkButton} onPress={handleSysDay}>
          <Text style={styles.linkButtonText}>打开系统日历</Text>
        </TouchableOpacity>
      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  containerScroll: {
    flexGrow: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
  },
  title: {
    fontSize: 20,
    fontWeight: "bold",
  },
  separator: {
    marginVertical: 30,
    height: 1,
    width: "80%",
  },
  recordingItem: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    padding: 25,
    borderBottomWidth: 1,
    borderBottomColor: "#ccc",
  },
  recordingNameInput: {
    height: 40,
    borderColor: "gray",
    borderWidth: 1,
    flex: 1,
    marginRight: 10,
  },
  recordingNameText: {
    flex: 1,
    marginRight: 10,
    height: 40,
    lineHeight: 40,
  },
  playingIndicator: {
    fontSize: 14,
    color: "red",
    marginLeft: 10,
  },
  linkButton: {
    marginTop: 20,
    padding: 10,
    backgroundColor: "#28a745",
    borderRadius: 5,
  },
  linkButtonText: {
    color: "#fff",
    fontSize: 16,
  },
});
